/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package guzik.lukasz.UsersExplorer;

import SnpDbEntities.User;
import SnpDbEntities.UserPermissions;
import guzik.lukasz.SnpDataAPI.SnpDataAPI;
import guzik.lukasz.SnpLoginEngine.interfaces.LoginEventListener;
import java.util.LinkedHashMap;
import java.util.logging.Logger;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import org.openide.util.NbBundle;
import org.openide.windows.TopComponent;
import org.openide.windows.WindowManager;
//import org.openide.util.ImageUtilities;
import org.netbeans.api.settings.ConvertAsProperties;
import org.openide.DialogDescriptor;
import org.openide.DialogDisplayer;
import org.openide.NotifyDescriptor;
import org.openide.util.Lookup;

/**
 * Top component which displays something.
 */
@ConvertAsProperties(dtd = "-//guzik.lukasz.UsersExplorer//UsersExplorer//EN",
autostore = false)
public final class UsersExplorerTopComponent extends TopComponent
	implements LoginEventListener
{
    private static UsersExplorerTopComponent instance;
    private LinkedHashMap<Integer, User> usersList;
    /** path to the icon used by the component and its open action */
//    static final String ICON_PATH = "SET/PATH/TO/ICON/HERE";
    private static final String PREFERRED_ID = "UsersExplorerTopComponent";

    public UsersExplorerTopComponent()
    {
	initComponents();
	setName(NbBundle.getMessage(UsersExplorerTopComponent.class, "CTL_UsersExplorerTopComponent"));
	setToolTipText(NbBundle.getMessage(UsersExplorerTopComponent.class, "HINT_UsersExplorerTopComponent"));
//        setIcon(ImageUtilities.loadImage(ICON_PATH, true));

    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jScrollPane1 = new javax.swing.JScrollPane();
        jUsersTree = new javax.swing.JTree();

        jUsersTree.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jUsersTreeMouseClicked(evt);
            }
        });
        jScrollPane1.setViewportView(jUsersTree);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 400, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 300, Short.MAX_VALUE)
        );
    }// </editor-fold>//GEN-END:initComponents

    private void jUsersTreeMouseClicked(java.awt.event.MouseEvent evt)//GEN-FIRST:event_jUsersTreeMouseClicked
    {//GEN-HEADEREND:event_jUsersTreeMouseClicked
	User selectedUser;
	User connectedUser = SnpDataAPI.getDefault().getConnectedUser();
	if(evt.getClickCount() == 2)
	{
	    DefaultMutableTreeNode selNode = (DefaultMutableTreeNode) jUsersTree.getLastSelectedPathComponent();

	    if(selNode != null && selNode.getUserObject() instanceof User)
	    {
		selectedUser = (User) selNode.getUserObject();
		selectedUser.setPwdHash("0");
		if((connectedUser.getPermissions() == UserPermissions.MODERATOR
			|| connectedUser.getPermissions() == UserPermissions.NORMAL_USER)
			&& connectedUser.getId() != selectedUser.getId())
		{
		    UserDetailsPanel detailsPanel = new UserDetailsPanel(selectedUser, false);
		    DialogDescriptor dd = new DialogDescriptor(detailsPanel,
			    "Szczegóły użytkownika", true, null);
		    dd.setClosingOptions(new Object[]
			    {
				DialogDescriptor.CLOSED_OPTION
			    });
		    dd.setOptions(new Object[]
			    {
				DialogDescriptor.CLOSED_OPTION
			    });
		    DialogDisplayer.getDefault().notify(dd);
		} else
		{
		    UserDetailsPanel detailsPanel = new UserDetailsPanel(selectedUser, true);
		    DialogDescriptor dd = new DialogDescriptor(detailsPanel,
			    "Szczegóły użytkownika", true, null);
		    dd.setClosingOptions(new Object[]
			    {
				DialogDescriptor.OK_OPTION, DialogDescriptor.CANCEL_OPTION
			    });
		    dd.setOptions(new Object[]
			    {
				DialogDescriptor.OK_OPTION, DialogDescriptor.CANCEL_OPTION
			    });

		    if(DialogDisplayer.getDefault().notify(dd) == DialogDescriptor.OK_OPTION)
		    {
			try
			{
			    selectedUser.setLogin(detailsPanel.jLoginTextField.getText());
			    selectedUser.setPwdHash(detailsPanel.pwdHash);
			    selectedUser.setName(detailsPanel.jNameTextField.getText());
			    selectedUser.setEmail(detailsPanel.jEmailTextField.getText());
			    selectedUser.setAbout(detailsPanel.jDescriptionTextArea.getText());
			    selectedUser.setEnabled(detailsPanel.jUserEnabledCheckbox.isSelected());
			    switch(detailsPanel.jPermissionsComboBox.getSelectedIndex())
			    {
				case 0:
				    selectedUser.setPermissions(UserPermissions.SUPER_ADMIN);
				    break;
				case 1:
				    selectedUser.setPermissions(UserPermissions.ADMIN);
				    break;
				case 2:
				    selectedUser.setPermissions(UserPermissions.MODERATOR);
				    break;
				default:
				    selectedUser.setPermissions(UserPermissions.NORMAL_USER);
			    }

			    SnpDataAPI.getDefault().updateUser(selectedUser);

			    for(int catId : detailsPanel.removedFromModerate)
			    {
				SnpDataAPI.getDefault().removeModeratorFromCategory(selectedUser.getId(), catId);
			    }

			    for(int catId : detailsPanel.addToModerate)
			    {
				SnpDataAPI.getDefault().addModeratorToCategory(selectedUser.getId(), catId);
			    }
			} catch(Exception e)
			{
			    NotifyDescriptor nd = new NotifyDescriptor.Message("Nie udało się zmienić użytkownika!",
				    NotifyDescriptor.ERROR_MESSAGE);
			    DialogDisplayer.getDefault().notify(nd);
			}
		    }
		}
	    }
	}
    }//GEN-LAST:event_jUsersTreeMouseClicked
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JTree jUsersTree;
    // End of variables declaration//GEN-END:variables

    /**
     * Gets default instance. Do not use directly: reserved for *.settings files only,
     * i.e. deserialization routines; otherwise you could get a non-deserialized instance.
     * To obtain the singleton instance, use {@link #findInstance}.
     */
    public static synchronized UsersExplorerTopComponent getDefault()
    {
	if(instance == null)
	{
	    instance = new UsersExplorerTopComponent();
	}
	return instance;
    }

    /**
     * Obtain the UsersExplorerTopComponent instance. Never call {@link #getDefault} directly!
     */
    public static synchronized UsersExplorerTopComponent findInstance()
    {
	TopComponent win = WindowManager.getDefault().findTopComponent(PREFERRED_ID);
	if(win == null)
	{
	    Logger.getLogger(UsersExplorerTopComponent.class.getName()).warning(
		    "Cannot find " + PREFERRED_ID + " component. It will not be located properly in the window system.");
	    return getDefault();
	}
	if(win instanceof UsersExplorerTopComponent)
	{
	    return (UsersExplorerTopComponent) win;
	}
	Logger.getLogger(UsersExplorerTopComponent.class.getName()).warning(
		"There seem to be multiple components with the '" + PREFERRED_ID
		+ "' ID. That is a potential source of errors and unexpected behavior.");
	return getDefault();
    }

    @Override
    public int getPersistenceType()
    {
	return TopComponent.PERSISTENCE_ALWAYS;
    }

    @Override
    public void componentOpened()
    {
	Lookup.getDefault().lookup(guzik.lukasz.SnpLoginEngine.interfaces.LoginEngineSPI.class).getLoginEngine().addLoginEventListener(instance);
	jUsersTree.setVisible(false);
    }

    @Override
    public void componentClosed()
    {
    }

    void writeProperties(java.util.Properties p)
    {
	// better to version settings since initial version as advocated at
	// http://wiki.apidesign.org/wiki/PropertyFiles
	p.setProperty("version", "1.0");
    }

    Object readProperties(java.util.Properties p)
    {
	if(instance == null)
	{
	    instance = this;
	}
	instance.readPropertiesImpl(p);
	return instance;
    }

    private void readPropertiesImpl(java.util.Properties p)
    {
	String version = p.getProperty("version");
    }

    @Override
    protected String preferredID()
    {
	return PREFERRED_ID;
    }

    @Override
    public void onLogin()
    {
	jUsersTree.setVisible(true);
	jUsersTree.setModel(new DefaultTreeModel(new DefaultMutableTreeNode("ROOT")));
	fillTree();
	jUsersTree.setRootVisible(true);
	jUsersTree.expandRow(0);
	jUsersTree.setRootVisible(false);

    }

    @Override
    public void onLogout()
    {
	jUsersTree.setVisible(false);
    }

    private void fillTree()
    {
	DefaultTreeModel model = (DefaultTreeModel) jUsersTree.getModel();
	DefaultMutableTreeNode treeRoot = (DefaultMutableTreeNode) model.getRoot();
	DefaultMutableTreeNode superAdmins = new DefaultMutableTreeNode("Super Admini");
	DefaultMutableTreeNode admins = new DefaultMutableTreeNode("Admini");
	DefaultMutableTreeNode moderators = new DefaultMutableTreeNode("Moderatorzy");
	DefaultMutableTreeNode normalUsers = new DefaultMutableTreeNode("Zwykli użytkownicy");

	model.insertNodeInto(superAdmins, treeRoot, 0);
	model.insertNodeInto(admins, treeRoot, 1);
	model.insertNodeInto(moderators, treeRoot, 2);
	model.insertNodeInto(normalUsers, treeRoot, 3);

	usersList = SnpDataAPI.getDefault().getUsersList();
	if(usersList == null)
	{
	    return;
	}

	for(User usr : usersList.values())
	{
	    switch(usr.getPermissions())
	    {
		case SUPER_ADMIN:
		    model.insertNodeInto(new DefaultMutableTreeNode(usr), superAdmins, 0);
		    break;

		case ADMIN:
		    model.insertNodeInto(new DefaultMutableTreeNode(usr), admins, 0);
		    break;

		case MODERATOR:
		    model.insertNodeInto(new DefaultMutableTreeNode(usr), moderators, 0);
		    break;

		case NORMAL_USER:
		    model.insertNodeInto(new DefaultMutableTreeNode(usr), normalUsers, 0);
		    break;
	    }
	}
    }
}
